#include "questionsyncer.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QUrl>
#include <QNetworkReply>

QuestionSyncer::QuestionSyncer(QObject* parent)
    : QObject(parent) {
    // 连接定时器信号
    connect(&syncTimer, &QTimer::timeout, this, &QuestionSyncer::onSyncTimer);
}

QuestionSyncer::~QuestionSyncer() {
}

void QuestionSyncer::startSyncQuestion(int intervalMinutes) {
    syncTimer.start(intervalMinutes * 60 * 1000);
    // 首次立即同步
    QTimer::singleShot(0, this, &QuestionSyncer::onSyncTimer);
}

qint64 QuestionSyncer::getLocalMaxQuestionId() {
    QSqlQuery query;
    query.exec("SELECT MAX(id) FROM Question");
    if (query.next()) {
        return query.value(0).toLongLong();
    }
    return 0; // 默认从 0 开始同步
}

void QuestionSyncer::onSyncTimer() {
    lastMaxId = getLocalMaxQuestionId();
    syncQuestions();
}

void QuestionSyncer::syncQuestions() {
    QString url = QString("http://47.109.75.129:3000/questions?since=%1").arg(lastMaxId);

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply* reply = networkManager.get(request);
    connect(reply, &QNetworkReply::finished, this, [this, reply]() {
        onFetchFinished(reply);
    });
}

void QuestionSyncer::onFetchFinished(QNetworkReply* reply) {
    if (reply->error() != QNetworkReply::NoError) {
        qWarning() << "get network fail:" << reply->errorString();
        reply->deleteLater();
        return;
    }

    QByteArray responseData = reply->readAll();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
    if (!jsonDoc.isArray()) {
        qWarning() << "reply data isn't JSON data";
        reply->deleteLater();
        return;
    }

    QJsonArray dataArray = jsonDoc.array();
    qDebug() << "sync " << dataArray.size() << " data";

    QSqlQuery query;
    query.prepare(R"(
        INSERT OR REPLACE INTO Question (
            id, type, content, choiceA, choiceB, choiceC, hint,
            is_custom, dynamic_rule, answer, grade
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    )");

    for (const QJsonValue& value : dataArray) {
        if (!value.isObject()) continue;
        QJsonObject obj = value.toObject();

        query.addBindValue(obj["id"].toInt());
        query.addBindValue(obj["type"].toString());
        query.addBindValue(obj["content"].toString());
        query.addBindValue(obj["choiceA"].toString());
        query.addBindValue(obj["choiceB"].toString());
        query.addBindValue(obj["choiceC"].toString());
        query.addBindValue(obj["hint"].isNull() ? QVariant(QVariant::String) : obj["hint"].toString());
        query.addBindValue(obj["is_custom"].toInt());
        query.addBindValue(obj["dynamic_rule"].isNull() ? QVariant(QVariant::String) : obj["dynamic_rule"].toString());
        query.addBindValue(obj["answer"].toString());
        query.addBindValue(obj["grade"].toInt());

        if (!query.exec()) {
            qWarning() << "insert data fail:" << query.lastError().text();
        }
    }

    reply->deleteLater();
}
